package com.coisshi.base.common.aop;

import cn.dev33.satoken.stp.StpUtil;
import com.coisshi.base.common.annotation.PreventDuplicateSubmit;
import com.coisshi.base.common.exception.BizException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

import static com.coisshi.base.common.constants.CacheKeyConstants.PREVENT_DUPLICATE_SUBMIT;

/**
 * 防止重复提交 切面
 */
@Aspect
@Component
@Slf4j
public class PreventDuplicateSubmitAspect {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Around("@annotation(preventDuplicateSubmit)")
    public Object around(ProceedingJoinPoint point, PreventDuplicateSubmit preventDuplicateSubmit) throws Throwable {
        // 生成防抖Key
        String loginId = StpUtil.getLoginIdAsString();

        String methodName = point.getSignature().toShortString();
        String key = PREVENT_DUPLICATE_SUBMIT + loginId + ":" + methodName;

        // 尝试存储 key
        Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", preventDuplicateSubmit.intervalTime(), TimeUnit.SECONDS);

        if (Boolean.FALSE.equals(success)) {
            // 已存在 key，说明正在防抖
            throw new BizException("操作过于频繁，请稍后再试");
        }

        // 正常放行
        return point.proceed();
    }
}
